package com.cs.framework.core.context;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.cs.framework.core.exception.CoreExceptionHelper;

/**
 * 上下文协助者
 * 
 * @author hedongzhou
 * 
 */
public class ContextHelper {

	protected static Log logger = LogFactory.getLog(ContextHelper.class);

	/**
	 * 创建应用上下文
	 * 
	 * @param applicationClass
	 *            应用上下文类型
	 * @param appConfig
	 *            应用上下文配置文件路径
	 * @param moduleCommonConfig
	 *            模块公共配置文件路径
	 * @return
	 */
	public static Application createApplication(String applicationClass, String appConfig, String moduleCommonConfig) {
		Application app = null;

		// 获取类型
		Class<?> cls = null;
		try {
			cls = Class.forName(applicationClass);
		} catch (ClassNotFoundException e) {
			logger.error(e.getMessage(), e);
			CoreExceptionHelper.throwCoreException(e, "CS015", applicationClass);
		}

		// 设置入参类型
		Class<?>[] paramTypes = new Class<?>[] { String.class, String.class };

		Constructor<?> constructor = null;
		try {
			// 获取构造方法
			constructor = cls.getConstructor(paramTypes);
		} catch (SecurityException e) {
			logger.error(e.getMessage(), e);
			CoreExceptionHelper.throwCoreException(e, "CS018", applicationClass);
		} catch (NoSuchMethodException e) {
			logger.error(e.getMessage(), e);
			CoreExceptionHelper.throwCoreException(e, "CS019", applicationClass);
		}

		try {
			// 创建对象
			app = (Application) constructor.newInstance(appConfig, moduleCommonConfig);
		} catch (IllegalArgumentException e) {
			logger.error(e.getMessage(), e);
			CoreExceptionHelper.throwCoreException(e, "CS020", applicationClass);
		} catch (InstantiationException e) {
			logger.error(e.getMessage(), e);
			CoreExceptionHelper.throwCoreException(e, "CS016", applicationClass);
		} catch (IllegalAccessException e) {
			logger.error(e.getMessage(), e);
			CoreExceptionHelper.throwCoreException(e, "CS017", applicationClass);
		} catch (InvocationTargetException e) {
			logger.error(e.getMessage(), e);
			CoreExceptionHelper.throwCoreException(e, "CS021", applicationClass);
		}

		return app;
	}

	/**
	 * 创建模块上下文
	 * 
	 * @param moduleClass
	 *            模块类型
	 * @param application
	 *            应用上下文
	 * @param moduleId
	 *            模块ID
	 * @param packagePath
	 *            模块包路径
	 * @return
	 */
	public static Module createModule(String moduleClass, Application application, String moduleId, String packagePath) {
		Module module = null;

		// 获取类型
		Class<?> cls = null;
		try {
			cls = Class.forName(moduleClass);
		} catch (ClassNotFoundException e) {
			logger.error(e.getMessage(), e);
			CoreExceptionHelper.throwCoreException(e, "CS001", moduleClass);
		}

		// 设置入参类型
		Class<?>[] paramTypes = new Class<?>[] { Application.class, String.class, String.class };

		Constructor<?> constructor = null;
		try {
			// 获取构造方法
			constructor = cls.getConstructor(paramTypes);
		} catch (SecurityException e) {
			logger.error(e.getMessage(), e);
			CoreExceptionHelper.throwCoreException(e, "CS004", moduleClass);
		} catch (NoSuchMethodException e) {
			logger.error(e.getMessage(), e);
			CoreExceptionHelper.throwCoreException(e, "CS005", moduleClass);
		}

		try {
			// 创建对象
			module = (Module) constructor.newInstance(application, moduleId, packagePath);
		} catch (IllegalArgumentException e) {
			logger.error(e.getMessage(), e);
			CoreExceptionHelper.throwCoreException(e, "CS006", moduleClass);
		} catch (InstantiationException e) {
			logger.error(e.getMessage(), e);
			CoreExceptionHelper.throwCoreException(e, "CS002", moduleClass);
		} catch (IllegalAccessException e) {
			logger.error(e.getMessage(), e);
			CoreExceptionHelper.throwCoreException(e, "CS003", moduleClass);
		} catch (InvocationTargetException e) {
			logger.error(e.getMessage(), e);
			CoreExceptionHelper.throwCoreException(e, "CS007", moduleClass);
		}

		return module;
	}

}
